﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.Caching;
using CY_MVC.Core;
using CY_MVC.Utility;

namespace CY_MVC.HttpHandlers
{
    public abstract class PageController : BaseController
    {
        #region 变量

        protected string TemplatePath = string.Empty;

        public string Title
        {
            set { Items[SeoHelper.SeoManagerTitleKey] = value; }
            get { return Items[SeoHelper.SeoManagerTitleKey].ToString(); }
        }

        public string Keywords
        {
            set { Items[SeoHelper.SeoManagerKeywordsKey] = value; }
            get { return Items[SeoHelper.SeoManagerKeywordsKey].ToString(); }
        }

        public string Description
        {
            set { Items[SeoHelper.SeoManagerDescriptionKey] = value; }
            get { return Items[SeoHelper.SeoManagerDescriptionKey].ToString(); }
        }



        public IDictionary<string, object> ViewData
        {
            set { Items["_ViewData_"] = value; }
            get { return (IDictionary<string, object>)Items["_ViewData_"]; }
        }

        #endregion

        #region protected函数

        protected void RegisterScript(string p_Script)
        {
            ScriptHelper.Add(p_Script);
        }

        protected enum ScriptType
        {
            Alart,
            Alart_Redirect,
            Redirect,
            Alart_Top_Redirect,
            Top_Redirect,
            Alart_Parent_Redirect,
            Parent_Redirect,
            Alart_ClosePage,
            ClosePage,
        }

        protected void RegisterScript(ScriptType p_ScriptType, params string[] p_Script)
        {
            switch (p_ScriptType)
            {
                case ScriptType.Alart:
                    ScriptHelper.Add("alert('" + p_Script[0] + "');");
                    break;
                case ScriptType.Alart_Redirect:
                    ScriptHelper.Add("alert('" + p_Script[0] + "');window.location.href='" + p_Script[1] + "';");
                    break;
                case ScriptType.Redirect:
                    ScriptHelper.Add("window.location.href='" + p_Script[0] + "';");
                    break;
                case ScriptType.Alart_Top_Redirect:
                    ScriptHelper.Add("alert('" + p_Script[0] + "');top.location.href='" + p_Script[1] + "';");
                    break;
                case ScriptType.Top_Redirect:
                    ScriptHelper.Add("top.location.href='" + p_Script[0] + "';");
                    break;
                case ScriptType.Alart_Parent_Redirect:
                    ScriptHelper.Add("alert('" + p_Script[0] + "');parent.location.href='" + p_Script[1] + "';");
                    break;
                case ScriptType.Parent_Redirect:
                    ScriptHelper.Add("parent.location.href='" + p_Script[0] + "';");
                    break;
                case ScriptType.Alart_ClosePage:
                    ScriptHelper.Add("alert('" + p_Script[0] + "');window.close();");
                    break;
                case ScriptType.ClosePage:
                    ScriptHelper.Add("window.close();");
                    break;
                default:
                    ScriptHelper.Add(p_Script[0]);
                    break;
            }
        }

        protected new bool IsPostBack()
        {
            return string.CompareOrdinal(Request.HttpMethod, "POST") == 0;
        }

        protected new bool IsPostBack(string p_BtnName)
        {
            return IsPostBack() && (Request.Form[p_BtnName] != null);
        }

        #endregion

        #region private函数

        private string ResponsePage()
        {
            Page_Load();
            for (var i = 0; i < Request.Form.Count; i++)
            {
                if (Request.Form.Keys[i] == null || Request.Form[i] == null) continue;
                if (!ViewData.ContainsKey(Request.Form.Keys[i]))
                {
                    ViewData[Request.Form.Keys[i]] = Request.Form[i];
                }
            }
            var View = string.IsNullOrEmpty(TemplatePath) ? ViewTemplateContext.GetView(this) : ViewTemplateContext.GetView(TemplatePath);

            var Pagetext = View.BuildString(ViewData);
            //销毁View对象,释放内存
            ViewData = null;

            Pagetext = WordFilterHelper.WordFilter(Pagetext);
            Pagetext = ResourceHelper.Generate(Pagetext);
            Pagetext = ScriptHelper.Generate(Pagetext);
            Pagetext = SeoHelper.Generate(Pagetext);

            return Pagetext;
        }

        #endregion

        public override void ProcessRequest(HttpContext p_Context)
        {
            Init(p_Context);

            ViewData = new Dictionary<string, object>();

            if (Request.UrlReferrer != null && IsPostBack() && Request.QueryString.Count > 0 && !string.IsNullOrEmpty(Request.QueryString[0]) && Request.Url.AbsolutePath.EndsWith(".axd", StringComparison.InvariantCultureIgnoreCase) && Request.UrlReferrer.Host == Request.Url.Host)
            {
                //Ajax请求下发类型为json数据
                Response.ContentType = "application/json;charset=UTF-8";
                Response.ContentEncoding = Encoding.UTF8;
                Response.Charset = "utf-8";
                
                byte[] ResultBytes = Encoding.UTF8.GetBytes(AjaxMethodContext.Invoke(this, Request.QueryString[0], Request.Form));

                if (StaticConfig.GzipLength != 0 && HttpGzip.CanGZip() && ResultBytes.Length > StaticConfig.GzipLength)
                {
                    Response.AppendHeader("Content-Encoding", "gzip");
                    ResultBytes = HttpGzip.GzipStr(ResultBytes);
                }
                Response.OutputStream.Write(ResultBytes, 0, ResultBytes.Length);
            }
            else
            {
                byte[] PageBytes;
                if (CacheSeconds > 0)
                {
                    DateTime DateLastModified = DateTime.MinValue;
                    if (!string.IsNullOrEmpty(p_Context.Request.Headers["If-Modified-Since"]))
                    {
                        DateTime.TryParse(p_Context.Request.Headers["If-Modified-Since"], out DateLastModified);
                    }
                    if (DateLastModified.AddSeconds(CacheSeconds) < DateTime.Now)
                    {
                        Response.Cache.SetExpires(DateTime.Now.AddSeconds(CacheSeconds));
                        Response.Cache.SetMaxAge(TimeSpan.FromSeconds(CacheSeconds));
                        Response.Cache.SetLastModified(DateTime.Now);
                        Response.Cache.SetCacheability(HttpCacheability.Public);

                        if (!DataCache.GetCache("CY_MVC.HttpHandlers.BaseController" + Request.RawUrl.ToLowerInvariant(), out PageBytes))
                        {
                            PageBytes = Encoding.UTF8.GetBytes(ResponsePage());
                            DataCache.SetCache("CY_MVC.HttpHandlers.BaseController" + Request.RawUrl.ToLowerInvariant(), PageBytes, DateTime.Now.AddSeconds(CacheSeconds), Cache.NoSlidingExpiration, CacheItemPriority.NotRemovable);
                        }

                        if (StaticConfig.GzipLength != 0 && HttpGzip.CanGZip() && PageBytes.Length > StaticConfig.GzipLength)
                        {
                            Response.AppendHeader("Content-Encoding", "gzip");
                            PageBytes = HttpGzip.GzipStr(PageBytes);
                        }

                        Response.BinaryWrite(PageBytes);
                    }
                    else
                    {
                        Response.ClearHeaders();
                        Response.Cache.SetLastModified(DateLastModified);
                        Response.Status = "304 Not Modified";
                        Response.AppendHeader("Content-Length", "0");
                    }
                }
                else
                {
                    PageBytes = Encoding.UTF8.GetBytes(ResponsePage());
                    if (StaticConfig.GzipLength != 0 && HttpGzip.CanGZip() && PageBytes.Length > StaticConfig.GzipLength)
                    {
                        Response.AppendHeader("Content-Encoding", "gzip");
                        PageBytes = HttpGzip.GzipStr(PageBytes);
                    }
                    Response.BinaryWrite(PageBytes);
                }
            }

            if (!HttpRuntime.UsingIntegratedPipeline) return;
            //判断是否处于集成管道模式下，否则的话无法执行下列方法
            Response.Headers.Remove("X-AspNet-Version");
            Response.Headers.Remove("Server");
            Response.Headers.Remove("ETag");
        }
    }
}
